package com.zdkj.common.data.mybatis.wrapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * @support: 三永华通科技有限公司
 * @author: cui_com
 * @version: 1.0
 * @Date: 2020-02-27 20:45
 * @Description: <p>
 * 自定义where条件
 * </p>
 */
public class CustomQueryWrapper<T> extends QueryWrapper<T> {

    protected final CustomQueryWrapper<T> typedThis = this;

    protected String alis = "";

    protected Class<T> entityClass;

    protected Object dto = null;

    protected Boolean delFlag = false;

    /**
     * 根据传入类型，生成where后的条件
     * <pre>
     *      暂时只支持String，Integer，其余类型后续添加
     * </pre>
     *
     * @param entityClass javabean对应table
     */
    public CustomQueryWrapper(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    /**
     * 根据传入类型，生成where后的条件
     * <pre>
     *      暂时只支持String，Integer，其余类型后续添加
     * </pre>
     */
    public CustomQueryWrapper<T> init() {
        T entity = fillEntity(entityClass, dto);
        super.setEntity(entity);
        super.initNeed();
        initCondition(entity, alis);
        return typedThis;
    }

    /**
     * @param dto 与javabean属性被包含关系
     * @return
     */
    public CustomQueryWrapper<T> addDTO(Object dto) {
        this.dto = dto;
        return typedThis;
    }

    /**
     * @param alis 字段别名
     * @return
     */
    public CustomQueryWrapper<T> addAlis(String alis) {
        this.alis = alis;
        return typedThis;
    }

    public CustomQueryWrapper<T> addDelFlag(Boolean flag) {
        this.delFlag = flag;
        return typedThis;
    }

    private T fillEntity(Class<T> entityClass, Object dto) {
        T entity = null;
        try {
            entity = entityClass.newInstance();
            BeanUtils.copyProperties(dto, entity);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return entity;
    }

    private void initCondition(T entity, String alis) {
        try {
            String prefix = StringUtils.isNotEmpty(alis) ? alis + StringPool.DOT : alis;
            Class cls = entity.getClass();
            List<TableFieldInfo> listField = SqlHelper.table(cls).getFieldList();
            for (TableFieldInfo info : listField) {
                if (delFlag && info.isLogicDelete()) {
                    addCondition(true, prefix + info.getColumn(), SqlKeyword.EQ, false);
                    continue;
                }
                Field f = cls.getDeclaredField(info.getProperty());
                f.setAccessible(true);
                Object value = f.get(entity);
                if (null != value && StringUtils.isNotEmpty(value.toString())) {
                    addCondition(true, prefix + info.getColumn(), SqlKeyword.EQ, value.toString());
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }


}
